---
interface Props {
  title: string;
  sidebar?: boolean;
  description?: string;
}

import {
  BookOpenText,
  Workflow,
  TableProperties,
  House,
  BookUser,
  BotMessageSquare,
  Users,
  Sparkles,
  Rocket,
  FileText,
  SquareDashedMousePointerIcon,
  PackageSearch,
  FileJson,
} from 'lucide-react';
import Header from '../components/Header.astro';
import SEO from '../components/Seo.astro';
import SideNav from '../components/SideNav/SideNav.astro';
import config from '@config';
import { getCollection } from 'astro:content';
import '@fontsource/inter';
import '@fontsource/inter/400.css'; // Specify weight
import '@fontsource/inter/700.css'; // Specify weight

import { getCommands } from '@utils/commands';
import { getDomains } from '@utils/collections/domains';
import { getEvents } from '@utils/events';
import { getServices } from '@utils/collections/services';
import { getFlows } from '@utils/collections/flows';
import { isCollectionVisibleInCatalog } from '@eventcatalog';
import { buildUrl } from '@utils/url-builder';
import { getQueries } from '@utils/queries';
import { hasLandingPageForDocs } from '@utils/pages';

const events = await getEvents({ getAllVersions: false });
const commands = await getCommands({ getAllVersions: false });
const queries = await getQueries({ getAllVersions: false });
const services = await getServices({ getAllVersions: false });
const domains = await getDomains({ getAllVersions: false });
const flows = await getFlows({ getAllVersions: false });
const customDocs = await getCollection('customPages');

import { isEventCatalogUpgradeEnabled, isVisualiserEnabled } from '@utils/feature';

// Try and load any custom styles if they exist
try {
  await import('../../eventcatalog.styles.css');
} catch (error) {}

const currentPath = Astro.url.pathname;

const catalogHasDefaultLandingPageForDocs = await hasLandingPageForDocs();

const getDefaultUrl = (route: string, defaultValue: string) => {
  if (route === 'docs/custom') {
    return customDocs.length > 0 ? buildUrl(`/${route}/${customDocs[0].id.replace('docs', '')}`) : buildUrl(defaultValue);
  }

  const collections = [
    { data: domains, key: 'domains' },
    { data: services, key: 'services' },
    { data: events, key: 'events' },
    { data: commands, key: 'commands' },
    { data: queries, key: 'queries' },
    { data: flows, key: 'flows' },
  ];

  for (const { data, key } of collections) {
    if (data.length > 0 && isCollectionVisibleInCatalog(key)) {
      // find the first item that has visualiser set to true
      const item = data.find((item) => item.data.visualiser !== false);
      if (item) {
        return buildUrl(`/${route}/${key}/${item.data.id}/${item.data.latestVersion}`);
      } else {
        continue;
      }
    }
  }

  return buildUrl(defaultValue);
};

const userSideBarConfiguration = config.sidebar || [];

const navigationItems = [
  {
    id: '/',
    label: 'Home',
    icon: House,
    href: buildUrl('/'),
    current: currentPath === '/',
    sidebar: false,
    hidden: !!config.landingPage,
  },
  {
    id: '/docs',
    label: 'Architecture Documentation',
    icon: BookOpenText,
    href: catalogHasDefaultLandingPageForDocs ? buildUrl('/docs') : getDefaultUrl('docs', '/docs'),
    current:
      (currentPath.includes('/docs') && !currentPath.includes('/docs/custom')) || currentPath.includes('/architecture/docs/'),
    sidebar: true,
  },
  {
    id: '/visualiser',
    label: 'Visualiser',
    icon: Workflow,
    href: getDefaultUrl('visualiser', '/visualiser'),
    current: currentPath.includes('/visualiser'),
    sidebar: true,
    hidden: !isVisualiserEnabled(),
  },

  {
    id: '/discover',
    label: 'Explore',
    icon: TableProperties,
    href: buildUrl('/discover/events'),
    current: currentPath.includes('/discover/'),
    sidebar: false,
  },
  {
    id: '/schemas',
    label: 'Schema Explorer',
    icon: FileJson,
    href: buildUrl('/schemas'),
    current: currentPath.includes('/schemas'),
    sidebar: false,
  },
  {
    id: '/directory',
    label: 'Users & Teams',
    icon: Users,
    href: buildUrl('/directory/users'),
    current: currentPath.includes('/directory'),
    sidebar: false,
  },
  {
    id: '/architecture',
    label: 'Architecture',
    icon: BookUser,
    href: buildUrl('/architecture/domains'),
    current: currentPath.includes('/architecture/'),
    sidebar: false,
    hidden: true,
  },
].filter((item) => {
  const userSideBarOption = userSideBarConfiguration.find((config: { id: string; visible: boolean }) => config.id === item.id);
  return userSideBarOption ? userSideBarOption.visible : true;
});

const studioNavigationItem = [
  {
    id: '/studio',
    label: 'EventCatalog Studio',
    icon: SquareDashedMousePointerIcon,
    href: buildUrl('/studio'),
    current: currentPath.includes('/studio'),
    sidebar: false,
  },
].filter((item) => {
  const userSideBarOption = userSideBarConfiguration.find((config: { id: string; visible: boolean }) => config.id === item.id);
  return userSideBarOption ? userSideBarOption.visible : true;
});

const premiumFeatures = [
  {
    id: '/docs/custom',
    label: 'Custom Documentation',
    icon: FileText,
    href: getDefaultUrl('docs/custom', '/docs/custom'),
    current: currentPath.includes('/docs/custom'),
    sidebar: false,
    isPremium: true,
  },
  {
    id: '/chat',
    label: 'EventCatalog Chat',
    icon: BotMessageSquare,
    href: buildUrl('/chat'),
    current: currentPath.includes('/chat'),
    isPremium: true,
  },
].filter((item) => {
  const userSideBarOption = userSideBarConfiguration.find((config: { id: string; visible: boolean }) => config.id === item.id);
  return userSideBarOption ? userSideBarOption.visible : true;
});

const currentNavigationItem = [...navigationItems, ...studioNavigationItem, ...premiumFeatures].find((item) => item.current);
const { title, description } = Astro.props;

const showSideBarOnLoad = currentNavigationItem?.sidebar;

const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
---

<!doctype html>
<html lang="en">
  <head>
    <SEO title={`EventCatalog | ${title}`} description={description} ogTitle={title} />
    <style is:global>
      .sidebar-transition {
        transition-property: width, transform;
        transition-duration: 300ms;
        transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
      }
      .tooltip {
        visibility: hidden;
        position: absolute;
      }
      .has-tooltip:hover .tooltip {
        visibility: visible;
        z-index: 100;
      }

      /* Hide anchor link by default */
      .anchor-link {
        display: inline-block;
        width: 1em;
        height: 1em;
        margin-left: 0.5rem;
        margin-top: 0.25rem;
        background-image: url('data:image/svg+xml,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cpath%20fill%3D%22currentColor%22%20d%3D%22m12.11%2015.39-3.88%203.88a2.52%202.52%200%200%201-3.5%200%202.47%202.47%200%200%201%200-3.5l3.88-3.88a1%201%200%200%200-1.42-1.42l-3.88%203.89a4.48%204.48%200%200%200%206.33%206.33l3.89-3.88a1%201%200%201%200-1.42-1.42Zm8.58-12.08a4.49%204.49%200%200%200-6.33%200l-3.89%203.88a1%201%200%200%200%201.42%201.42l3.88-3.88a2.52%202.52%200%200%201%203.5%200%202.47%202.47%200%200%201%200%203.5l-3.88%203.88a1%201%200%201%200%201.42%201.42l3.88-3.89a4.49%204.49%200%200%200%200-6.33ZM8.83%2015.17a1%201%200%200%200%201.1.22%201%201%200%200%200%20.32-.22l4.92-4.92a1%201%200%200%200-1.42-1.42l-4.92%204.92a1%201%200%200%200%200%201.42Z%22/%3E%3C/svg%3E');
        background-repeat: no-repeat;
        background-position: center;
        background-size: 1em 1em;
        opacity: 0;
        transition: opacity 0.2s ease-in-out;
        text-decoration: none;
        vertical-align: -2px;
      }

      /* Show icon on heading hover */
      h1:hover .anchor-link,
      h2:hover .anchor-link,
      h3:hover .anchor-link,
      h4:hover .anchor-link,
      h5:hover .anchor-link,
      h6:hover .anchor-link {
        opacity: 1;
      }

      /* Show on keyboard focus */
      .anchor-link:focus {
        opacity: 1;
        outline: none;
      }
    </style>
  </head>
  <body>
    <Header />
    <div class="flex">
      <aside class="flex" id="eventcatalog-vertical-nav">
        <div
          class="fixed flex flex-col items-center w-16 h-screen py-4 bg-white bg-gradient-to-b from-white to-gray-100 border-r border-gray-200 z-20 shadow-md justify-between"
        >
          <nav class="flex flex-col h-[calc(100vh-70px)] justify-between">
            <div class="flex flex-col items-center flex-1 space-y-6">
              {
                navigationItems
                  .filter((item) => !item.hidden)
                  .map((item) => {
                    return (
                      <a
                        id={item.id}
                        data-role="nav-item"
                        href={item.href}
                        class={`p-1.5 inline-block transition-colors duration-200 rounded-lg ${
                          item.current
                            ? 'text-white bg-gradient-to-b from-purple-500 to-purple-700'
                            : 'hover:bg-gradient-to-r hover:from-purple-500 hover:to-purple-700 hover:text-white text-gray-700'
                        }`}
                      >
                        <div class="has-tooltip">
                          <span class="tooltip rounded shadow-lg p-1 text-xs bg-gradient-to-l from-purple-500 to-purple-700 text-white ml-10">
                            {item.label}
                          </span>
                          <item.icon className="h-6 w-6" />
                        </div>
                      </a>
                    );
                  })
              }

              <hr class="w-8 border-t border-gray-200" />

              {
                studioNavigationItem.length > 0 && (
                  <a
                    id={studioNavigationItem[0].id}
                    data-role="nav-item"
                    href={studioNavigationItem[0].href}
                    class={`p-1.5 inline-block pt-1 pb-1 mt-0 mb-0 transition-colors duration-200 rounded-lg relative ${studioNavigationItem[0].current ? 'text-white bg-gradient-to-b from-purple-500 to-purple-700' : 'hover:bg-gradient-to-r hover:from-purple-500 hover:to-purple-700 hover:text-white text-gray-700'}`}
                  >
                    <div class="has-tooltip">
                      <span class="tooltip rounded shadow-lg p-1 text-xs bg-gradient-to-l from-purple-500 to-purple-700 text-white ml-10">
                        {studioNavigationItem[0].label}
                      </span>
                      <SquareDashedMousePointerIcon className="h-6 w-6" />
                    </div>
                  </a>
                )
              }

              {studioNavigationItem.length > 0 && <hr class="w-8 border-t border-gray-200" />}

              {
                premiumFeatures.map((item) => (
                  <a
                    id={item.id}
                    data-role="nav-item"
                    href={item.href}
                    class={`p-1.5 inline-block transition-colors duration-200 rounded-lg mb-8 relative ${
                      item.current
                        ? 'text-white bg-gradient-to-b from-purple-500 to-purple-700'
                        : 'hover:bg-gradient-to-r hover:from-purple-500 hover:to-purple-700 hover:text-white text-gray-700'
                    }`}
                  >
                    <div class="has-tooltip">
                      <span class="tooltip rounded shadow-lg p-1 text-xs bg-gradient-to-l from-indigo-500 to-indigo-700 text-white ml-10 flex items-center gap-1">
                        <Sparkles className="h-3 w-3" /> {item.label}
                      </span>
                      <item.icon className="h-6 w-6" />
                      <div class="absolute -top-1 -right-1 bg-gradient-to-r from-amber-400 to-amber-500 rounded-full p-0.5 shadow-lg">
                        <Sparkles className="h-2 w-2 text-white" />
                      </div>
                    </div>
                  </a>
                ))
              }
            </div>

            {
              isEventCatalogUpgradeEnabled() && (
                <div class="mb-4">
                  <a
                    id="/pro"
                    data-role="nav-item"
                    href={buildUrl('/plans')}
                    class={`p-1.5 inline-block transition-colors duration-200 rounded-lg ${currentPath.includes('/pro') ? 'text-white bg-gradient-to-b from-purple-500 to-purple-700' : 'bg-gradient-to-r from-purple-100 to-indigo-100 hover:from-purple-500 hover:to-purple-700 hover:text-white text-purple-700'}`}
                  >
                    <div class="has-tooltip">
                      <span class="tooltip rounded shadow-lg p-1 text-xs bg-gradient-to-l from-purple-500 to-purple-700 text-white ml-10">
                        Upgrade EventCatalog
                      </span>
                      <Rocket className="h-6 w-6" />
                    </div>
                  </a>
                </div>
              )
            }
          </nav>
        </div>

        <SideNav
          id="sidebar"
          class={`sidebar-transition h-content  overflow-y-auto bg-white  border-r border-gray-100 w-[22em] ml-16 ${showSideBarOnLoad ? 'block' : 'hidden'}`}
        />
      </aside>
      <main
        class={`sidebar-transition w-full max-h-content overflow-y-auto ${showSideBarOnLoad ? 'ml-0' : 'ml-16'}`}
        id="content"
      >
        <slot />
      </main>

      <!-- Create a overlay that tells people to purchase backstage plugin if they want to embed the page -->
      <div class="absolute inset-0 bg-black items-center justify-center z-50 hidden" id="embed-overlay">
        <div class="text-white text-center space-y-4">
          <div>
            <h1 class="text-2xl font-bold">EventCatalog Backstage Integration</h1>
            <p class="text-md text-red-500">Missing license key for backstage integration.</p>
          </div>
          <div>
            <p class="text-sm text-gray-500">Please configure the backstage plugin to embed this page into Backstage.</p>
            <a href="https://www.eventcatalog.dev/integrations/backstage" class="text-blue-500 text-xs"
              >Configure backstage plugin &rarr;</a
            >
          </div>
        </div>
      </div>
    </div>
  </body>
</html>
<script define:vars={{ navigationItems, currentNavigationItem, showSideBarOnLoad, canPageBeEmbedded }}>
  // Listen for Astro transititions
  document.addEventListener('astro:page-load', () => {
    document.dispatchEvent(new CustomEvent('contentLoaded'));
  });

  // Listen for DOM loaded
  document.addEventListener('DOMContentLoaded', () => {
    document.dispatchEvent(new CustomEvent('contentLoaded'));
  });

  document.addEventListener('contentLoaded', () => {
    // Users can add ?embed=true to the URL to hide the navigation
    const urlSearchParams = new URLSearchParams(window.location.search);
    const params = Object.fromEntries(urlSearchParams.entries());
    const embeded = params.embed === 'true' ? true : false;
    const content = document.getElementById('content');

    if (embeded && !canPageBeEmbedded) {
      const overlay = document.getElementById('embed-overlay');
      overlay.style.display = 'flex';
      return;
    }

    if (embeded) {
      const elementsToHide = [
        'eventcatalog-vertical-nav',
        'eventcatalog-header',
        'eventcatalog-header-spacer',
        'visualiser-footer',
        // /discover page elements
        'discover-collection-tabs',
        'discover-title',
      ];

      elementsToHide.forEach((id) => {
        const element = document.getElementById(id);
        if (element) element.style.display = 'none';
      });

      content.classList.remove('ml-16');
      return;
    }

    const sidebar = document.getElementById('sidebar');
    const currentPath = window.location.href;

    // Hide the sidebar if the current navigation item is not a sidebar item
    if (!currentNavigationItem?.sidebar) {
      sidebar.style.display = 'none';
      content.style.width = '100%';
      content.classList.add('ml-16');
    } else {
      sidebar.style.display = 'block';
    }

    const navItems = document.querySelectorAll('[data-role="nav-item"]');
    let isOpen = showSideBarOnLoad;

    navItems.forEach((item) => {
      item.addEventListener('click', (e) => {
        const currentPath = window.location.href;
        const id = item.getAttribute('id');

        const navItem = navigationItems.find((navItem) => navItem.id === id);

        if (!navItem.sidebar || !currentPath.includes(navItem.id) || currentPath.includes('/docs/custom')) {
          window.location.href = navItem.href;
          return;
        }

        // not on the target page then just go to it.
        if (!currentPath.includes(navItem.id)) return;

        if (currentPath.includes(navItem.id)) {
          e.preventDefault();
          if (isOpen) {
            hideSidebar();
          } else {
            showSidebar();
          }
        }
      });
    });

    function showSidebar() {
      if (!sidebar || !content) return;
      isOpen = true;
      localStorage.setItem('sidebarState', 'open');
      sidebar.style.display = 'block';
      setTimeout(() => {
        sidebar.style.transform = 'translateX(0)';
        content.style.transform = 'translateX(0)';
        content.classList.remove('ml-16');
        content.style.width = 'calc(100% - 240px)';
      }, 10);
    }

    function hideSidebar() {
      if (!sidebar || !content) return;
      isOpen = false;
      sidebar.style.transform = 'translateX(-100%)';
      content.style.transform = 'translateX(0px)';
      content.style.width = '100%';
      content.classList.add('ml-16');
    }

    if (sidebar) {
      sidebar.addEventListener('transitionend', () => {
        if (!isOpen && sidebar && content) {
          sidebar.style.display = 'none';
          content.style.transform = 'translateX(0px)';
        }
      });
    }

    // Listen for custom sidebar toggle event from React components
    window.addEventListener('sidebarToggle', (event) => {
      const { action } = event.detail;
      if (action === 'hide') {
        hideSidebar();
      } else if (action === 'show') {
        showSidebar();
      }
    });
  });
</script>
